<script setup>
import { defineExpose, onMounted, ref } from 'vue'
import { area, layerInfo, locationMedia } from "@/utils/api.js"
import olMap from "ol/Map";
import View from "ol/View";
import * as olProj from "ol/proj";
import { Vector as VectorSource, XYZ } from "ol/source";
import { Tile as TileLayer, Image as ImageLayer, Vector as VectorLayer } from "ol/layer";
import { defaults as defaultControls, OverviewMap } from 'ol/control';
import ImageWMS from 'ol/source/ImageWMS';
import { Circle as CircleStyle, Fill, Stroke, Style, Text, Icon } from 'ol/style';
import GeoJSON from "ol/format/GeoJSON";
import Overlay from "ol/Overlay";
import close from '@/assets/icon/close.svg';
const emit = defineEmits(['PopUp', 'send'])

let closer = null;
let container = null;
let PopOverlay = null;
import "ol/ol.css";

let areaId = '';
const base = ref([]);
const other = ref([]);
const lw = ref(0)
const radio = ref('天地图');
const checkList = ref([]);
let map = null;
let totalMap = {};
let vectorSource = null;

const SwitchLayers = (data) => {
    if (lw.value == data) {
        lw.value = 0;
    } else {
        lw.value = data;
    }
}

const getarea = async () => {
    let res = await area(areaId)
    if (res) {
        let d = res.data.mapConfig;
        init(d.lon, d.lat, d.level);

    }
}

const getlayerInfo = async () => {
    let params = {
        areaId: areaId,
        userId: ""
    }
    let res = await layerInfo(params)
    if (res.code == '200') {
        base.value = res.data.base;
        base.value.forEach(e => {
            if (e.name === '天地图') {
                addXYZ('baseLayer', e.layerUrl)
            }
        })
        other.value = res.data.other;
        other.value.forEach(e => {
            if (e.selected) {
                drawWMS(e.id, e.layerUrl, e.layerName, e.styleId, e.cql);
                checkList.value.push(e.name)
            }
        })
    }
}

const init = (lon, lat, level) => {
    let center = [lon, lat]; // 地图的初始中心点
    container = document.getElementById('popup');
    closer = document.getElementById('popup-closer');
    PopOverlay = new Overlay({
        element: container,
        autoPan: {
            animation: {
                duration: 250,
            },
        },
    });
    map = new olMap({
        target: 'map',
        layers: [],
        overlays: [PopOverlay],
        controls: defaultControls({
            attribution: false,
            zoom: false,
            rotate: false
        }).extend([new OverviewMap()]),
        view: new View({
            //设置中心点
            center: olProj.fromLonLat(center),
            zoom: 11,
        })
    });

    getlayerInfo();

    map.on('singleclick', function (evt) {
        let feature = map.forEachFeatureAtPixel(evt.pixel,
            function (feature) {
                return feature;
            });

        var coordinate = olProj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');

        emit('send', coordinate)

        if (feature != undefined && feature) {
            if (feature.get("data") != undefined) {
                let fdata = feature.get("data");
                let params = '?id=' + fdata.id + '&type=' + fdata.type;
                locationMedia(params).then(res => {
                    if (res.code == '200') {
                        // console.log(res);
                        emit('PopUp', res.data)
                    }
                })
            }
        }
        // const coordinate = evt.coordinate;
        // PopOverlay.setPosition(coordinate);
    });

    // closer.onclick = function () {
    //     PopOverlay.setPosition(undefined);
    //     closer.blur();
    //     return false;
    // };

};

const addXYZ = (item, url) => {
    if (typeof (totalMap[item]) != "undefined") {
        map.removeLayer(totalMap[item]);
        delete totalMap[item];
    }
    totalMap[item] = new TileLayer({
        source: new XYZ({
            url: url
        })
    },
    )
    map.addLayer(totalMap[item])
};

//绘制wms类型
const drawWMS = (item, url, name, styleId, cql) => {
    if (typeof (totalMap[item]) != "undefined") {
        map.removeLayer(totalMap[item]);
        delete totalMap[item];
    } else {
        let params = {
            'LAYERS': name,
            'STYLES': styleId,
            'CQL_FILTER': "[" + cql + "]"
        };

        totalMap[item] = new ImageLayer({
            source: new ImageWMS({
                url: url,
                params: params,
                serverType: 'geoserver'
            })
        })
        map.addLayer(totalMap[item]);
    }
};

const previewshape = (data, id) => {
    //判断是否已经存在相同id的图层 如果有删掉，再重新绘制
    if (typeof (totalMap[id]) != "undefined") {
        map.removeLayer(totalMap[id]);
        delete totalMap[id];
    }
    let styleFunction = function () {
        return function (feature, resolution) {
            //点
            if (feature.getGeometry().getType() == 'Point') {
                if (feature.get('fillColor').indexOf('#') != -1) {
                    var point = new Style({
                        image: new CircleStyle({
                            radius: feature.get("radius"),
                            fill: new Fill({
                                color: feature.get("fillColor")
                            }),
                            stroke: new Stroke({
                                color: feature.get("borderColor"),
                                width: feature.get("size")
                            })
                        }),
                        text: new Text({
                            font: '16px Microsoft YaHei',
                            text: feature.get('name'),
                            fill: new Fill({
                                color: '#fff'
                            }),
                            offsetY: 15,
                            stroke: new Stroke({
                                color: '#4C4ADD',
                                width: 1
                            }),
                        })
                    })
                } else {
                    var point = new Style({
                        image: addImage(feature, resolution),
                        text: new Text({
                            font: '16px Microsoft YaHei',
                            text: feature.get('name'),
                            fill: new Fill({
                                color: '#fff'
                            }),
                            offsetY: 15,
                            stroke: new Stroke({
                                color: '#4C4ADD',
                                width: 1
                            }),
                        })
                    })
                }
                return [point]
            }
            if (feature.getGeometry().getType() == 'MultiPoint') {
                var MultiPoint = new Style({
                    image: new CircleStyle({
                        radius: 5,
                        fill: new Fill({
                            color: feature.get("fillColor")
                        }),
                        stroke: new Stroke({
                            color: feature.get("borderColor"),
                            width: feature.get("size")
                        })
                    }),
                    text: new Text({
                        font: '12px Calibri,sans-serif',
                        text: feature.get('text'),
                        fill: new Fill({
                            color: feature.get('fillColor')
                        }),
                        offsetY: 15,
                        stroke: new Stroke({
                            color: 'white',
                            width: 1
                        }),
                    })
                })
                return [MultiPoint]
            }
            //面
            if (feature.getGeometry().getType() == 'MultiPolygon') {
                var MultiPolygon = new Style({
                    stroke: new Stroke({
                        color: feature.get('borderColor'),
                        width: feature.get("size")
                    }),
                    fill: new Fill({
                        color: feature.get("fillColor")
                    }),
                    text: new Text({
                        font: '16px Calibri,sans-serif',
                        text: feature.get('text'),
                        fill: new Fill({
                            color: feature.get('textColor')
                        }),
                        stroke: new Stroke({
                            color: feature.get('textColor'),
                            width: 1
                        })
                    })
                })
                return [MultiPolygon]
            }
            if (feature.getGeometry().getType() == 'Polygon') {
                var Polygon = new Style({
                    stroke: new Stroke({
                        color: feature.get('borderColor'),
                        width: feature.get("size")
                    }),
                    fill: new Fill({
                        color: feature.get("fillColor")
                    }),
                    text: new Text({
                        font: '12px Calibri,sans-serif',
                        text: feature.get('text'),
                        fill: new Fill({
                            color: feature.get('borderColor')
                        }),
                        stroke: new Stroke({
                            color: 'white',
                            width: 3
                        }),
                    })
                })
                return [Polygon]
            }
            //线
            if (feature.getGeometry().getType() == 'LineString') {
                var LineString = new Style({
                    stroke: new Stroke({
                        color: feature.get('borderColor'),
                        width: 2
                    }),
                    fill: new Fill({
                        color: feature.get("fillColor"),
                        width: 2
                    }),
                    text: new Text({
                        font: '12px Calibri,sans-serif',
                        text: feature.get('text'),
                        fill: new Fill({
                            color: 'white'
                        }),
                        stroke: new Stroke({
                            color: 'block',
                            width: 2
                        }),
                    })
                })
                return [LineString]
            }
            //多线
            if (feature.getGeometry().getType() == 'MultiLineString') {
                var MultiLineString = new Style({
                    stroke: new Stroke({
                        color: feature.get('borderColor'),
                        width: feature.get("size") + 3
                    }),
                    text: new Text({
                        font: '12px Calibri,sans-serif',
                        text: feature.get('text'),
                        fill: new Fill({
                            color: 'white'
                        }),
                        stroke: new Stroke({
                            color: 'block',
                            width: 2
                        }),
                    })
                })
                return [MultiLineString]
            }
        }
    };
    let geojsonObject = {
        'type': 'FeatureCollection',
        'crs': {
            'type': 'name',
            'properties': {
                'name': 'EPSG:4326'
            }
        },
        'features': []
    };
    vectorSource = new VectorSource({
        features: (new GeoJSON(
            {
                defaultDataProjection: 'EPSG:4326',
                featureProjection: 'EPSG:3857'
            }
        )).readFeatures(geojsonObject)
    });
    totalMap[id] = new VectorLayer({
        source: vectorSource,
        style: styleFunction()
    });
    let sources = totalMap[id].getSource();
    data.forEach((e => {
        sources.addFeatures(
            (new GeoJSON({
                defaultDataProjection: 'EPSG:4326',
                featureProjection: 'EPSG:3857'
            })).readFeatures({
                "id": e.id,
                "properties": {
                    "name": e.name,
                    "borderColor": e.borderColor,
                    "fillColor": e.fillColor,
                    "iconSrc": e.iconSrc,
                    "data": e.data
                },
                'type': 'Feature',
                'geometry': e.geojson
            }))
    }));
    totalMap[id].set("altitudeMode", "clampToGround");
    map.addLayer(totalMap[id]);
    totalMap[id].setZIndex(99)
    // let centerid = data[0].id,
    //     thisfeature = vectorSource.getFeatureById(centerid),
    //     center = thisfeature.getGeometry().getFirstCoordinate();
    // map.getView().setCenter(center);
};
//点类型绘制图标 需要定位图标位置
//地图图标位置处理函数
const addImage = (feature, resolution) => {
    let src = feature.get('iconSrc');
    let anchor = [0, 1];
    //根据图标文件名 设置定位点  地图上放置的图标更改文件名即可保持一致
    if (src != '') {
        if (src.indexOf('anchor_bottom_center') != -1) {
            anchor = [0.5, 1];
        } else if (src.indexOf('anchor_bottom_left') != -1) {
            anchor = [0, 1];
        } else if (src.indexOf('anchor_bottom_right') != -1) {
            anchor = [1, 1];
        } else if (src.indexOf('anchor_center_center') != -1) {
            anchor = [0.5, 0.5];
        } else if (src.indexOf('anchor_top_center') != -1) {
            anchor = [0.5, 0];
        } else if (src.indexOf('anchor_top_left') != -1) {
            anchor = [0, 0];
        } else if (src.indexOf('anchor_top_right') != -1) {
            anchor = [1, 0];
        }
        return new Icon({
            src: feature.get('iconSrc'),
            anchor: [0.5, 1],
            scale: 0.5
        });
    }
};

const locationM = (center) => {
    map.getView().setCenter(olProj.fromLonLat(center));
    map.getView().setZoom(18);
}

const delIlayer = (item) => {
    if (typeof (totalMap[item]) != "undefined") {
        map.removeLayer(totalMap[item]);
        delete totalMap[item];
    }
}

onMounted(() => {
    areaId = JSON.parse(window.sessionStorage.getItem('usermsg')).areaId;
    getarea();

})
defineExpose({
    previewshape, delIlayer, locationM
})
</script>
<template>
    <div id="map">
        <div class="map-menu">
            <div>
                <img src="/src/assets/img/l1.png" @click.stop="SwitchLayers(1)" alt="">
                <div class="mm-layers" v-if="lw == 1">
                    <el-radio-group v-model="radio">
                        <el-radio v-for="(i, index) in base" :label="i.name"
                            @change="addXYZ('baseLayer', i.layerUrl)">{{
                                i.name }}</el-radio>
                    </el-radio-group>
                </div>
            </div>
            <div>
                <img src="/src/assets/img/l2.png" @click.stop="SwitchLayers(2)" alt="">
                <div class="mm-layers" v-if="lw == 2">
                    <el-checkbox-group v-model="checkList">
                        <el-checkbox v-for="(i, index) in other"
                            @change="drawWMS(i.id, i.layerUrl, i.layerName, i.styleId, i.cql)" :label="i.name" />
                    </el-checkbox-group>
                </div>
            </div>
        </div>

        <!-- 地图弹窗  ↓-->
        <div id="popup" class="ol-popup" v-if="false">
            <div class="d-lkb-c" id="popup-closer">
                <img :src="close" alt="">
            </div>
            <div id="popup-content">
                <div class="popup-img">

                </div>
            </div>
        </div>

    </div>
</template>
<style scoped>
#map {
    width: 100%;
    height: 100%;
    position: relative;
}

.map-menu {
    display: flex;
    align-items: center;
    position: absolute;
    top: 16px;
    left: 16px;
    z-index: 22;
    /* overflow: hidden; */
    cursor: pointer;
}

.map-menu>div {
    width: 40px;
    height: 40px;
    margin-left: 16px;
    position: relative;
}

.map-menu>div img {
    width: 100%;
    height: 100%;
}

.mm-layers {
    padding: 20px 0 20px 20px;
    background-color: #FFFFFF;
    border-radius: 4px;
    position: absolute;
    top: 52px;
    left: 0;
    z-index: 2;
    /* overflow: hidden; */
}

.mm-layers::before {
    content: "";
    position: absolute;
    top: -10px;
    left: 20px;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 12px solid transparent;
    border-right: 12px solid transparent;
    border-bottom: 12px solid #FFFFFF;
}
</style>

<style>
.ol-popup {
    width: 450px;
    /* height: 4.6rem; */
    padding: 0 16px;
    position: absolute;
    bottom: 12px;
    left: -50px;
    background-color: white;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
    padding: 15px;
    border-radius: 10px;
    border: 1px solid #cccccc;
}

.ol-popup:after,
.ol-popup:before {
    top: 100%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}

.ol-popup:after {
    border-top-color: white;
    border-width: 10px;
    left: 48px;
    margin-left: -10px;
}

.ol-popup:before {
    border-top-color: #cccccc;
    border-width: 11px;
    left: 48px;
    margin-left: -11px;
}

.d-lkb-c {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 2;
    cursor: pointer;
}

.popup-img {
    width: 100%;
    height: 300px;
    background-color: #000;
    display: flex;
    align-items: center;
    justify-content: center;
}


.popup-img img {
    width: 100%;
    height: 100%;
}

.popup-img video {
    width: 100%;
    height: 100%;
}
</style>